/*  File Name	: MySqlDB.h
 *  Author		: Javie Pong
 *	 E-mail		: 823960168@qq.com
 *  Created on	: 2012-7-31
 *  Description : in order to avoid Memory leak,you must use
 *  			'std:auto_ptr' when you use mysql pointer
 */

#ifndef MYSQLDB_H_
#define MYSQLDB_H_

#include <list>
#include "mysql_connection.h"
#include "mysql_driver.h"
#include "cppconn/statement.h"
#include "cppconn/resultset.h"
#include "CommonStruct.h"
#include "DBMonitor.h"

#define MAX_CONNECT	5

class EnginePlayer;
class ChatPlayer;
class DBPlayer;
class MyConnection;

using namespace sql;

class MySqlDB
{
public:
	typedef std::list<sql::Connection*> SqlConnPool;

	MySqlDB();
	virtual ~MySqlDB();

	//static MySqlDB *instance(void);
	int init(std::string ip,int port,std::string db,std::string user,std::string pwd);

	int create_local_role(int roleid,std::string account,std::string pwd,int sex);
	int create_global_role(int roleid,std::string account,std::string pwd,int sex);
	int check_account(DBPlayer *player);
	int get_total_chips(int roleid);
	int borrow_chips(const int roleid,const int &chips);
	int giveback_chips(const int roleid,const int &chips);

	int create_name_key(std::string account);
	int delete_name_key(int roleid);
	int save_name_key(DBPlayer *player);

	int load_account_info(EnginePlayer *player);
	int save_account_info(EnginePlayer *player);

	int save_chips_record(ChipsRecord *record);

	int chater_load_info(ChatPlayer *info);

	int update_tableid(EnginePlayer *player);
	int update_roomid(EnginePlayer *player);

	int load_name_map(AccountMap &map);

	MyConnection get_conn(void);
	void release_conn(sql::Connection* conn);

	const DBInfo &dbinfo(void);
private:
	int init_conn(void);
	void destory_conn(void);
	sql::Connection* new_conn(void);
	void destory(ResultSet* rs, Statement* prep_stmt=NULL);

private:
	//static MySqlDB *instance_;

	mysql::MySQL_Driver *driver_;

	char url[128];
	DBInfo db_info_;

	RT_MUTEX rt_mutex_;

	//conn pool
	int cur_size_;
	SqlConnPool local_conn_pool_;
};

///////////////////////////////////////////////
class MyConnection
{
public:
	MyConnection(MySqlDB *conn_pool,sql::Connection* conn=NULL)
	{
		this->conn_ = conn;
		this->conn_pool_ = conn_pool;
	}
	virtual ~MyConnection()
	{
		if(NULL!=this->conn_pool_)
		{
			this->conn_pool_->release_conn(this->conn_);
			this->conn_pool_ = NULL;
			this->conn_ = NULL;
		}
	}
	sql::Connection* conn_;

private:
	MySqlDB *conn_pool_;
};

#define MYSQL_INSTANCE  MySqlDB::instance()

/*
#define EXCEPTION_CATCH(X,SQL_ERROR,RETURN)  \
	try\
	{\
		X \
	}\
	catch(sql::SQLException &e) \
	{\
		LOG((ERROR_LOG,"1-ErrorCode:[%d],SQLState:[%s] description:[%s]",\
		e.getErrorCode(),e.getSQLState().c_str(),e.what()));\
		try\
		{\
			SQL_ERROR\
		}\
		catch(sql::SQLException &e)\
		{\
			LOG((ERROR_LOG,"2-ErrorCode:[%d],SQLState:[%s] description:[%s]",\
					e.getErrorCode(),e.getSQLState().c_str(),e.what()));\
		}\
		RETURN\
	}\
	catch(...)\
	{\
		LOG((ERROR_LOG,"Unknown error..."));	\
		RETURN\
	}\
*/

#endif /* MYSQLDB_H_ */
